#ifndef MAINAPP_H
#define MAINAPP_H

#include <QApplication>
#include <QPointer>
#include <QObject>

class QJSEngine;
class QQmlEngine;
class QQmlApplicationEngine;
class QTranslator;

class MainApp : public QApplication
{
    Q_OBJECT

    Q_PROPERTY(int demoNum READ demoNum WRITE setDemoNum NOTIFY demoNumChanged)

    Q_PROPERTY(QString language READ language WRITE setLanguage NOTIFY languageChanged)
public:
    static QObject* GetInstance(QQmlEngine* engine, QJSEngine* scriptEngine);

public:
    MainApp(int &argc, char **argv);
    ~MainApp() override;
    
    int Main(int argc, char* argv[]);
    
public:
    // 只有信号、槽以及被标记成Q_INVOKABLE的方法才能够被其它线程所触发调用
    // 将方法声明为Q_INVOKABLE，并且在另一线程中用invokeMethod唤起
    // For QML invokable function(s)
    Q_INVOKABLE void testFunc();
    
    Q_INVOKABLE void changeLanguage(QString language);
    
    // For QML property(-ies)
    // e.g.
    // demoNum
    int demoNum() const;
    void setDemoNum(int newValue);

    QString language() const;
    void setLanguage(QString newValue);

signals:
    void demoNumChanged(int newValue);

    void languageChanged(QString newValue);    

public slots:

private slots:

private:
    bool Initialize();
    bool Uninitialize();

    bool InitializePath();
    bool UninitializePath();

    bool InitializeCfg();
    bool UninitializeCfg();

    bool InitializeTranslator();
    bool UninitializeTranslator();

    bool InitializeQmlEngine();
    bool UninitializeQmlEngine();

    bool InitializeUI(QQmlApplicationEngine* pQmlEngine);
    bool UninitializeUI(QQmlApplicationEngine* pQmlEngine);

    bool InitializeOthers();
    bool UninitializeOthers();

private:
    QString                                     m_strAppRootPath;
    QString                                     m_strImageRootPath;

    QScopedPointer<QTranslator>                 m_pTranslator;
    QScopedPointer<QQmlApplicationEngine>       m_pQmlEngine;

    int                                         m_mDemoNum{0};

    QString                                     m_mLanguage{""};
};

MainApp* GetMainApp();

#endif // MAINAPP_H
